package com.gf.framework.common.result;

import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.apache.skywalking.apm.toolkit.trace.Trace;
import org.apache.skywalking.apm.toolkit.trace.TraceContext;

import java.time.LocalDateTime;

/**
 * http返回的包装类
 */
@Setter
@Getter
public class R<T> {
    @ApiModelProperty("状态码")
    private String code;
    @ApiModelProperty("内容")
    private String message;
    @ApiModelProperty("链路id")
    private String traceId;
    @ApiModelProperty("返回数据内容")
    private T data;
    @ApiModelProperty("时间")
    private LocalDateTime time = LocalDateTime.now();

    public R() {
        this(BaseResultCodeEnum.SUCCESS.getCode(), BaseResultCodeEnum.SUCCESS.getMessage());
    }

    public R(String code, String message) {
        this.code = code;
        this.message = message;
        this.setTraceId();
    }

    public R(IResultCode resultCode) {
        this(resultCode.getCode(), resultCode.getMessage());
    }

    public R(IResultCode resultCode, T data) {
        this(resultCode);
        this.data = data;
    }

    public R(String code, String message, T data) {
        this(code, message);
        this.data = data;
    }

    public static <T> R<T> success(T data) {
        R<T> objectDataResult = new R<T>();
        objectDataResult.setData(data);
        return objectDataResult;
    }

    public static <T> R<T> success() {
        R<T> objectDataResult = new R<T>();
        objectDataResult.setData(null);
        return objectDataResult;
    }

    public static <T> R<T> fail(IResultCode resultCode, T t) {
        return new R<T>(resultCode.getCode(), resultCode.getMessage(), t);
    }

    public static <T> R<T> fail(String code, String message, T t) {
        return new R<T>(code, message, t);
    }

    public static <T> R<T> fail(IResultCode resultCode) {
        return new R<T>(resultCode.getCode(), resultCode.getMessage(), null);
    }

    public static <T> R<T> fail(String code, String message) {
        return new R<T>(code, message, null);
    }

    @Trace
    public void setTraceId() {
        this.traceId = TraceContext.traceId();
    }

}
